package app.handler;

import app.vo.ResultResponse;
import app.utils.LoggerUtil;
import app.utils.RedisTemplateUtils;
import com.alibaba.fastjson.JSON;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationListener;
import org.springframework.security.authentication.event.AuthenticationFailureBadCredentialsEvent;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.*;

@Component
public class LoginFailHandler implements AuthenticationFailureHandler, ApplicationListener<AuthenticationFailureBadCredentialsEvent> {
    //private static final Logger LOG = Logger.getLogger(LoginFailHandler.class);
    @Autowired
    private ResultResponse resultResponse;
    @Autowired
    private RedisTemplateUtils redisTemplateUtils;

    //身份验证失败处理程序
    @Override
    public void onAuthenticationFailure(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AuthenticationException e) throws IOException {
        resultResponse.setCode(401);
        resultResponse.setMessage("登录失败");
        resultResponse.setData(e.getMessage());
        ResultResponse resultResponse = new ResultResponse(this.resultResponse.getCode(), this.resultResponse.getMessage(), this.resultResponse.getState(), this.resultResponse.getData());
        httpServletResponse.setCharacterEncoding("UTF-8");
        httpServletResponse.getWriter().write(JSON.toJSONString(resultResponse));
    }

    @Override
    public void onApplicationEvent(AuthenticationFailureBadCredentialsEvent event) {
        //获取用户输入的用户名
        String userName = (String) event.getAuthentication().getPrincipal();
        Map<Object, Object> objects;
        //获取redis中存储的用户名
        objects = redisTemplateUtils.hmget(userName+"Frequency");
        //LoggerUtil.info(LOG, "参数:{0}", userName+"Frequency");
        //判断redis中没有用户名信息的时候执行这个逻辑
        if (objects.size() == 0) {
            //每个用户第一次输错密码写入第一次机会 一共三次机会
            HashMap<String, Object> map = new HashMap<String, Object>();
            map.put(userName+"Frequency", 1);
            //设置redis用户名与输错密码次数
            redisTemplateUtils.hmset(userName+"Frequency", map);
            //获取redis中的用户名与输错密码次数
            objects = redisTemplateUtils.hmget(userName+"Frequency");
            for (Map.Entry<Object, Object> entry : objects.entrySet()) {
                //返回前端输错密码次数
                resultResponse.setState((Integer) entry.getValue());
            }
        } else {
            //比对用户输入的用户名与redis中存入的用户名是否一样
            objects = redisTemplateUtils.hmget(userName+"Frequency");
            for (Map.Entry<Object, Object> entry : objects.entrySet()) {
                HashMap<String, Object> map = new HashMap<String, Object>();
                map.put(userName+"Frequency", (Integer) entry.getValue() + 1);
                redisTemplateUtils.hmset(userName+"Frequency", map);
                objects = redisTemplateUtils.hmget(userName+"Frequency");
                for (Map.Entry<Object, Object> entrys : objects.entrySet()) {
                    //返回前端输错密码次数
                    resultResponse.setState((Integer) entrys.getValue());
                }
            }
        }
    }
}
